package com.afdor.rws.event.channel.local;

import com.afdor.rws.annotation.extension.Extension;
import com.afdor.rws.core.extension.ExtensionLoader;
import com.afdor.rws.event.channel.AbstractChannelProvider;
import com.afdor.rws.event.channel.ChannelProvider;
import com.afdor.rws.event.channel.client.consumer.EventConsumer;
import com.afdor.rws.event.channel.client.consumer.handler.EventHandler;
import com.afdor.rws.event.channel.client.producer.EventProducer;
import com.afdor.rws.event.channel.local.observer.ObserverEventSource;
import com.afdor.rws.event.config.EventConfigUtils;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.ToString;

/**
 * 本地事件消息通道
 *
 * @author 悭梵
 * @date Created in 2018-08-08 10:38
 */
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Extension(value = "local", order = Extension.NORMAL_ORDER - 100, interfaceClass = ChannelProvider.class)
public class LocalEventChannelProvider extends AbstractChannelProvider {

    private ObserverEventSource eventSource = new ObserverEventSource();

    /**
     * 生产者
     */
    private volatile EventProducer eventProducer;

    @Override
    public LocalEventChannelProvider init() {
        return this;
    }

    @NonNull
    @Override
    protected EventConsumer createEventConsumer(@NonNull String eventSourceName, @NonNull EventHandler eventHandler) {
        String eventConsumerName = EventConfigUtils.getProperty(EventConfigUtils.EVENT_CONSUMER_NAME);
        /* 构建并设置消费者对象 */
        return ExtensionLoader
                .getInstance(EventConsumer.class)
                .newExtension(eventConsumerName, eventSource)
                .setEventHandler(eventHandler)
                .setEventSourceName(eventSourceName);
    }

    @NonNull
    @Override
    protected EventProducer getEventProducer() {
        if (eventProducer == null) {
            String eventProduceName = EventConfigUtils.getProperty(EventConfigUtils.EVENT_PRODUCER_NAME);
            eventProducer = ExtensionLoader
                    .getInstance(EventProducer.class)
                    .newExtension(eventProduceName, eventSource)
                    .init();
        }
        return eventProducer;
    }
}
